package com.neusoft.bizcore.auth.stress;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import com.neusoft.bizcore.auth.enums.AuthPermissionType;
import com.neusoft.bizcore.auth.model.AuthOganization;
import com.neusoft.bizcore.auth.model.AuthPermission;
import com.neusoft.bizcore.auth.model.AuthRole;
import com.neusoft.bizcore.auth.model.AuthUser;
import com.neusoft.bizcore.auth.repository.AuthOganizationRepository;
import com.neusoft.bizcore.auth.repository.AuthPermissionRepository;
import com.neusoft.bizcore.auth.repository.AuthRoleRepository;
import com.neusoft.bizcore.auth.repository.AuthUserRepository;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Profile("stress")
@Component
public class InitialStressData implements ApplicationListener<AuthFixtureEvent> {
    @Autowired
    private AuthOganizationRepository authOganizationRepository;
    @Autowired
    private AuthUserRepository authUserRepository;
    @Autowired
    private AuthRoleRepository authRoleRepository;
    @Autowired
    private AuthPermissionRepository authPermissionRepository;

    @Override
    public void onApplicationEvent(AuthFixtureEvent event) {
        this.init();
    }

    public void init() {
        this.initUser();
    }

    // 共创建110个组织，10个一级组织，100个二级组织
    private List<AuthOganization> initOrgs() {
        InitialStressData.log.info(">>>>>>>>>>>>>>>init org begin<<<<<<<<<<<<<<<");
        final AuthOganization rootOrg = this.authOganizationRepository.findByCode("root");
        final List<AuthOganization> orgs = new ArrayList<>();
        // 10个一级组织
        for (int i = 0; i < 10; i++) {
            final AuthOganization org1 = new AuthOganization();
            org1.setCode("level-1-" + (i + 1));
            org1.setName("一级组织-" + (i + 1));
            org1.setParent(rootOrg);
            this.authOganizationRepository.save(org1);

            // 每个一级组织下挂10个二级组织
            for (int j = 0; j < 10; j++) {
                final AuthOganization org2 = new AuthOganization();
                org2.setCode("level-2-" + ((i * 10) + (j + 1)));
                org2.setName("二级组织-" + ((i * 10) + (j + 1)));
                org2.setParent(org1);
                this.authOganizationRepository.save(org2);

                orgs.add(org2);
            }
        }
        InitialStressData.log.info(">>>>>>>>>>>>>>>init org end<<<<<<<<<<<<<<<");
        return orgs;
    }

    // 创建500个菜单权限，1000个按钮权限
    private Map<String, List<AuthPermission>> initPerm() {
        InitialStressData.log.info(">>>>>>>>>>>>>>>init permission begin<<<<<<<<<<<<<<<");
        final Map<String, List<AuthPermission>> map = new HashedMap<>();
        map.put("menu", new ArrayList<>());
        map.put("action", new ArrayList<>());

        for (int i = 0; i < 500; i++) {
            final AuthPermission p = new AuthPermission();
            p.setName("菜单-" + (i + 1));
            p.setCode("p-menu-" + (i + 1));
            p.setType(AuthPermissionType.menu);
            this.authPermissionRepository.save(p);

            map.get("menu").add(p);
        }

        for (int i = 0; i < 1000; i++) {
            final AuthPermission p = new AuthPermission();
            p.setName("按钮-" + (i + 1));
            p.setCode("p-button-" + (i + 1));
            p.setType(AuthPermissionType.action);
            this.authPermissionRepository.save(p);

            map.get("action").add(p);
        }

        InitialStressData.log.info(">>>>>>>>>>>>>>>init permission end<<<<<<<<<<<<<<<");
        return map;

    }

    // 创建10个角色, 每个角色有50个菜单权限和100个按钮权限
    private List<AuthRole> initRole() {

        InitialStressData.log.info(">>>>>>>>>>>>>>>init role begin<<<<<<<<<<<<<<<");
        final Map<String, List<AuthPermission>> permissions = this.initPerm();

        final List<AuthRole> roles = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            final AuthRole role = new AuthRole();
            role.setCode("role-" + +(i + 1));
            role.setName("角色-" + +(i + 1));
            final List<AuthPermission> partial = new ArrayList<>();
            partial.addAll(permissions.get("menu").subList(i * 50, (i + 1) * 50));
            partial.addAll(permissions.get("action").subList(i * 100, (i + 1) * 100));
            role.setPermissions(partial);
            this.authRoleRepository.save(role);
            roles.add(role);
        }

        InitialStressData.log.info(">>>>>>>>>>>>>>>init role end<<<<<<<<<<<<<<<");

        return roles;
    }

    // 创建500个用户， 每个用户2个角色， 每个用户2个组织
    private void initUser() {

        final AuthUser tmp = this.authUserRepository.findByUsername("user0");
        if (null != tmp) {
            return;
        }
        final List<AuthOganization> orgs = this.initOrgs();
        final List<AuthRole> roles = this.initRole();

        InitialStressData.log.info(">>>>>>>>>>>>>>>init user begin<<<<<<<<<<<<<<<");
        for (int i = 0; i < 500; i++) {
            final AuthUser user = new AuthUser();
            user.setUsername("user" + i);
            user.setName("用户-" + i);
            user.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
            user.setMail("user" + i + "@neusoft.com");
            user.setPhone("18888888888");
            user.setRoles(Arrays.asList(roles.get((i * 2) % 10), roles.get(((i * 2) % 10) + 1)));
            user.setOganizations(Arrays.asList(orgs.get((i * 2) % 100), orgs.get(((i * 2) % 100) + 1)));

            this.authUserRepository.save(user);

        }
        InitialStressData.log.info(">>>>>>>>>>>>>>>init user end<<<<<<<<<<<<<<<");
    }

}
